﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace GBT.Client.FileOperation
{
    public static class FileIcon
    {
        public enum Size
        {
            Icon,
            SmallIcon,
            LargeIcon
        }

        /// <summary>
        ///获取文件的默认图标 
        /// </summary>
        /// <param name="fileName">文件名。可以只是文件名，甚至只是文件的扩展名(.*)； 如果想获得.ICO文件所表示的图标，则必须是文件的完整路径。 </param>
        /// <param name="largeIcon">是否大图标 文件的默认图标 </param>
        /// <returns></returns>
        public static Icon GetFileIcon(this string fileName, bool largeIcon)
        {
            SHFILEINFO info = new SHFILEINFO(true);
            int cbFileInfo = Marshal.SizeOf(info);
            SHGFI flags;
            if (largeIcon)
                flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
            else
                flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
            SHGetFileInfo(fileName, 256, out info, (uint)cbFileInfo, flags);
            return Icon.FromHandle(info.hIcon);
        }

        /// <summary>
        ///获取本地文件的默认图标 
        /// </summary>
        /// <param name="fileName">文件的完整路径</param>
        /// <param name="size">Size.SmallIcon 小图标，Size.LargeIcon 大图标</param>
        /// <returns></returns>
        public static Icon GetFileIcon(this string fileName, Size size)
        {
            int IconCount = ExtractIconEx(fileName, -1, null, null, 0);
            IntPtr[] largeIcons = new IntPtr[IconCount];
            IntPtr[] smallIcons = new IntPtr[IconCount];
            ExtractIconEx(fileName, 0, largeIcons, smallIcons, IconCount);
            Icon icon = null;
            if (size == Size.SmallIcon)
            {
                icon = Icon.FromHandle(smallIcons[0]);
            }
            else if (size == Size.LargeIcon)
            {
                Icon.FromHandle(largeIcons[0]);
            }
            return icon;
        }

        [DllImport("shell32.dll")]
        private static extern int ExtractIconEx(string lpszFile, int niconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons);

        [DllImport("Shell32.dll")]
        private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags);

        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEINFO
        {
            public SHFILEINFO(bool b)
            {
                hIcon = IntPtr.Zero;
                iIcon = 0; dwAttributes = 0;
                szDisplayName = "";
                szTypeName = "";
            }

            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
            public string szTypeName;
        };

        private enum SHGFI
        {
            SmallIcon = 0x00000001,
            LargeIcon = 0x00000000,
            Icon = 0x00000100,
            DisplayName = 0x00000200,
            Typename = 0x00000400,
            SysIconIndex = 0x00004000,
            UseFileAttributes = 0x00000010
        }
    }

}
